mod login;
pub use login::{user_login,change_password,init_password};

use shq_common::prelude::{AuthType, ColumnRange, Permission, RowRange};

use crate::cache::UserPermission;
pub async fn get_user_perm(user_id: u32, perm_id: u32) -> anyhow::Result<Option<Permission>> {
    let mut up = UserPermission::new()?;
    let perm = up.get_user_permission(user_id, perm_id).await?;
    Ok(perm)
}
pub async fn user_has_role(user_id: u32, role_id: u32) -> anyhow::Result<bool> {
    let mut up = UserPermission::new()?;
    let role_ids = up.get_user_role_ids(user_id).await?;
    let has = role_ids.contains(&role_id);
    Ok(has)
}
pub async fn get_user_role_ids(user_id: u32) -> anyhow::Result<Vec<u32>> {
    let mut up = UserPermission::new()?;
    let role_ids = up.get_user_role_ids(user_id).await?;
    Ok(role_ids)
}
pub async fn get_role_user_ids(role_id:u32) -> anyhow::Result<Vec<u32>> {
    let mut up = UserPermission::new()?;
    let user_ids = up.get_role_user_ids(role_id).await?;
    Ok(user_ids)
}
pub async fn has_auth_type(
    user_id: u32,
    perm_id: u32,
    auth_type: AuthType,
) -> anyhow::Result<bool> {
    let mut up = UserPermission::new()?;
    let perm = up.get_user_permission(user_id, perm_id).await?;
    Ok(perm
        .map(|p| p.auth_types.contains(&auth_type))
        .unwrap_or(false))
}

pub async fn has_row_range(
    user_id: u32,
    perm_id: u32,
    row_range: RowRange,
) -> anyhow::Result<bool> {
    let mut up = UserPermission::new()?;
    let perm = up.get_user_permission(user_id, perm_id).await?;
    Ok(perm
        .map(|p| {
            p.row_ranges.len() == 0
                || p.row_ranges.iter().any(|r| {
                    let l: u8 = r.clone().into();
                    let r: u8 = row_range.clone().into();
                    l >= r
                })
        })
        .unwrap_or(false))
}

pub async fn get_row_range(user_id: u32, perm_id: u32) -> anyhow::Result<RowRange> {
    let mut up = UserPermission::new()?;
    let perm = up.get_user_permission(user_id, perm_id).await?;
    let range=perm
        .map(|p| {
            let range = p.row_ranges.iter().max().cloned();
            Some(range.unwrap_or(RowRange::All))
        })
        .unwrap_or(None);
    Ok(range.unwrap_or(RowRange::OneSelf))
}

pub async fn has_column_range(
    user_id: u32,
    perm_id: u32,
    column_range: &ColumnRange,
) -> anyhow::Result<bool> {
    let mut up = UserPermission::new()?;
    let perm = up.get_user_permission(user_id, perm_id).await?;
    Ok(perm
        .map(|p| p.column_ranges.contains(column_range))
        .unwrap_or(false))
}
